home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / technote / tchntstc.sit / Technical Notes Stack 3.2.1 / Technical Notes Stack 3.2.1 / card_32724.txt < prev    next >
Encoding:
Text File  |  1990-01-08  |  7.4 KB  |  143 lines

  1. -- card: 32724 from stack: in.1
  2. -- bmap block id: 0
  3. -- flags: 0000
  4. -- background id: 2711
  5. -- name: 101 CreateResFile and the Poor Man╒s Search Path
  6.  
  7.  
  8. -- part contents for background part 9
  9. ----- text -----
  10. #101: CreateResFile and the Poor ManΓÇÖs Search Path
  11.  
  12. See also:     The File Manager
  13.               The Resource Manager
  14.               Technical Note #77 ΓÇö HFS Ruminations
  15.  
  16. Written by:    Jim Friedlander    January 12, 1987
  17. Updated:                          March 1, 1988
  18. _______________________________________________________________________________
  19.  
  20. CreateResFile checks to see if a resource file with a given name exists, and if it does, returns a dupFNErr (ΓÇô48) error. Unfortunately, to do this check, CreateResFile uses a call that follows the Poor ManΓÇÖs Search Path (PMSP).
  21. _______________________________________________________________________________
  22.  
  23. CreateResFile checks to see if a resource file with a given name exists, and if it does, returns a dupFNErr (ΓÇô48) error. Unfortunately, to do the check, CreateResFile calls PBOpenRF, which uses the Poor ManΓÇÖs Search Path (PMSP). For example, if we have a resource file in the System folder named ΓÇÿMyFileΓÇÖ (and no file with that name in the current directory) and we call CreateResFile('MyFile'), ResError will return a dupFNErr, since PBOpenRF will search the current directory first, then search the blessed folder on the same volume. This makes it impossible to use CreateResFile to create the resource file ΓÇÿMyFileΓÇÖ in the current directory if a file with the same name already exists in a directory thatΓÇÖs in the PMSP.
  24.  
  25. To make sure that CreateResFile will create a resource file in the current directory whether or not a resource file with the same name already exists further down the PMSP, call _Create (PBCreate or Create) before calling CreateResFile:
  26.  
  27.     err := Create('MyFile',0,myCreator,myType);
  28.         {0 for VRefNum means current volume/directory}
  29.     CreateResFile('MyFile');
  30.     err := ResError; {check for error}
  31.  
  32. In MPW C:
  33.  
  34.     err = Create("\pMyFile",0,myCreator,myType);
  35.     CreateResFile("\pMyFile");
  36.     err = ResError();
  37.  
  38. This works because _Create does not use the PMSP. If we already have ΓÇÿMyFileΓÇÖ in the current directory, _Create will fail with a dupFNErr, then, if ΓÇÿMyFileΓÇÖ has an empty resource fork, CreateResFile will write a resource map, otherwise, CreateResFile will return dupFNErr. If there is no file named ΓÇÿMyFileΓÇÖ in the current directory, _Create will create one and then CreateResFile will write the resource map.
  39. Notice that we are intentionally ignoring the error from _Create, since we are calling it only to assure that a file named ΓÇÿMyFileΓÇÖ does exist in the current directory.
  40.  
  41. Please note that SFPutFile does not use the PMSP, but that FSDelete does. SFPutFile returns the vRefNum/WDRefNum of the volume/folder that the user selected. If your program deletes a resource file before creating one with the same name based on information returned from SFPutFile, you can use the following strategy to avoid deleting the wrong file, that is, a file that is not in the directory specified by the vRefNum/WDRefNum returned by SFPutFile, but in some other directory in the PMSP:
  42.  
  43.     VAR    
  44.         wher    : Point;
  45.         reply   : SFReply;
  46.         err     : OSErr;
  47.         oldVol  : Integer;
  48.  
  49.     ...
  50.  
  51.         wher.h := 80; wher.v := 90;
  52.         SFPutFile(wher,'','',NIL,reply);
  53.         IF reply.good THEN BEGIN
  54.             err := GetVol(NIL,oldVol); {So we can restore it later}
  55.             err := SetVol(NIL,reply.vRefNum);{for the CreateResFile call}
  56.  
  57.         {Now for the Create/CreateResFile calls to create a resource file that
  58.          we know is in the current directory}
  59.  
  60.             err := Create(reply.fName,reply.vRefNum,myCreator,myType);
  61.             CreateResFile(reply.fName); {weΓÇÖll use the ResError from this ...}
  62.  
  63.             CASE ResError OF
  64.                 noErr:{the create succeeded, go ahead and work with the new                          resource file -- NOTE: at this point, we donΓÇÖt know
  65.                          whatΓÇÖs in the data fork of the file!!} ;
  66.                 dupFNErr: BEGIN {duplicate file name error}
  67.                     {the file already existed, so, letΓÇÖs delete it. WeΓÇÖre now                      sure that weΓÇÖre deleting the file in the current directory}
  68.  
  69.                         err:= FSDelete(reply.fName,reply.vRefNum);
  70.                         
  71.                     {now that weΓÇÖve deleted the file, letΓÇÖs create the new one,                      again, we know this will be in the current directory}
  72.  
  73.                         err:= Create(reply.fName,reply.vRefNum,myCreator,myType);
  74.                         CreateResFile(reply.fName);
  75.                 END; {CASE dupFNErr}
  76.                 OTHERWISE       {handle other errors} ;
  77.             END;                {Case ResError}
  78.             err := SetVol(NIL,oldVol);{restore the default directory}
  79.         END;                    {If reply.good}
  80.     ...
  81.  
  82. In MPW C:
  83.  
  84.         Point     wher;
  85.         SFReply   reply;
  86.         OSErr     err;
  87.         short     oldVol;
  88.  
  89.  
  90.         wher.h = 80; wher.v = 90;
  91.         SFPutFile(wher,"","",nil,&reply);
  92.         if (reply.good )
  93.         {
  94.             err = GetVol(nil,&oldVol);        /*So we can restore it later*/
  95.             err = SetVol(nil,reply.vRefNum);  /*for the CreateResFile call*/
  96.  
  97.             /*Now for the Create/CreateResFile calls to create a resource file             that we know is in the current directory*/
  98.  
  99.             err = Create(&reply.fName,reply.vRefNum,myCreator,myType);
  100.             CreateResFile(&reply.fName);/*weΓÇÖll use the ResError from this ...*/
  101.  
  102.             switch    (ResError()) 
  103.             {
  104.                 case noErr:;/*the create succeeded, go ahead and work with the                                 new resource file -- NOTE: at this point, we donΓÇÖt know whatΓÇÖs in the data fork of the file!!*/ 
  105.                      break; /* case noErr*/
  106.                 case dupFNErr: /*duplicate file name error*/
  107.                         /*the file already existed, so, letΓÇÖs delete it. WeΓÇÖre now sure that weΓÇÖre deleting the file in the current directory*/
  108.  
  109.                           err= FSDelete(&reply.fName,reply.vRefNum);
  110.                         
  111.                             /*now that weΓÇÖve deleted the file, letΓÇÖs create the                             new one, again, we know this will be in the current directory*/
  112.  
  113.                             err= Create(&reply.fName,reply.vRefNum,                                         myCreator,myType);
  114.                             CreateResFile(&reply.fName);
  115.                     break;    /*case dupFNErr*/
  116.                 default:;     /*handle other errors*/ 
  117.             }     /* switch */
  118.             err = SetVol(nil,oldVol);/*restore the default directory*/
  119.         }                    /*if reply.good*/
  120.  
  121.  
  122. NOTE: OpenResFile uses the PMSP too, so you may have to adopt similar 
  123.       strategies to make sure that you are opening the desired resource file 
  124.       and not some other file further down the PMSP. This is normally not a 
  125.       problem if you use SFGetFile, since SFGetFile does not use the PMSP, in 
  126.       fact, SFGetFile does not open or close files, so it doesnΓÇÖt run into this 
  127.       problem.
  128.  
  129.  
  130.  
  131. -- part contents for background part 2
  132. ----- text -----
  133. 101
  134.  
  135. -- part contents for background part 7
  136. ----- text -----
  137. CreateResFile and the Poor ManΓÇÖs Search Path
  138.  
  139. -- part contents for background part 113
  140. ----- text -----
  141. File Manager
  142. Resource Manager
  143. Technical Note #77